package cn.enilu.flash.service.transport;

import cn.enilu.flash.bean.dto.transport.MapPointDto;
import cn.enilu.flash.bean.dto.transport.UserAddressFindDto;
import cn.enilu.flash.bean.dto.transport.UserAddressSaveDto;
import cn.enilu.flash.bean.entity.transport.MapPoint;
import cn.enilu.flash.bean.entity.transport.UserAddress;
import cn.enilu.flash.bean.exception.ApplicationException;
import cn.enilu.flash.bean.exception.ApplicationExceptionEnum;
import cn.enilu.flash.bean.vo.query.SearchFilter;
import cn.enilu.flash.bean.vo.transport.UserAddressVo;
import cn.enilu.flash.dao.transport.MapPointRepository;
import cn.enilu.flash.dao.transport.UserAddressRepository;
import cn.enilu.flash.service.BaseService;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class UserAddressService extends BaseService<UserAddress,Long, UserAddressRepository> {


    @Autowired
    private MapPointRepository mapPointRepository;
    @Autowired
    private UserAddressRepository userAddressRepository;


    public UserAddressSaveDto save(final UserAddressSaveDto saveDto){

        MapPoint mapPoint = toMapPoint(saveDto.getPoint());
        UserAddress addressInfo = userAddressValidateAndInit(saveDto);
        try {
            mapPoint = mapPointRepository.save(mapPoint);
            addressInfo.setMapPointId(mapPoint.getId());
            if(addressInfo.getId() != null){
                addressInfo = this.update(addressInfo);
            }else{
                addressInfo = this.insert(addressInfo);
            }
        } catch (Exception e) {
            log.error("用户地址保存失败,开始回滚 e>>",e);
            if(mapPoint.getId() != null){
                mapPointRepository.deleteById(mapPoint.getId());
            }
            if(addressInfo.getId() != null){
                this.deleteById(addressInfo.getId());
            }
            throw new ApplicationException(ApplicationExceptionEnum.USER_ADDRESS_SAVE_ERROR);
        }
        return saveDto;
    }


    public List<UserAddressVo> queryAddressByUser(UserAddressFindDto findDto){
        SearchFilter filter = SearchFilter.build("createBy", SearchFilter.Operator.EQ, findDto.getUserId());
        SearchFilter filter1 = SearchFilter.build("point.pointType", SearchFilter.Operator.EQ, 3);
        List<UserAddress> list = queryAll(Lists.newArrayList(filter,filter1), Sort.by(Sort.Direction.ASC, "orderBy"));
        if(CollectionUtils.isEmpty(list)){
            return Collections.EMPTY_LIST;
        }

        List<UserAddressVo> voList = Lists.newArrayListWithExpectedSize(list.size());
        for(UserAddress entity : list){
            UserAddressVo vo = new UserAddressVo();
            vo.setAddressId(entity.getId());
            vo.setContactName(entity.getContactName());
            vo.setContactPhone(entity.getContactPhone());
            vo.setAddressDetail(entity.getAddressDetail());
            MapPoint point = entity.getPoint();
            if(point != null){
                StringBuilder sb = new StringBuilder();
                if(StrUtil.isNotBlank(point.getProvince())){
                    sb.append(point.getProvince());
                }
                if(StrUtil.isNotBlank(point.getCity())){
                    sb.append(point.getCity());
                }
                if(StrUtil.isNotBlank(point.getDistrict())){
                    sb.append(point.getDistrict());
                }
                vo.setCityDistrict(sb.toString());


                UserAddressVo.MapPointVo pointVo = new UserAddressVo.MapPointVo();
                pointVo.setAddDetail(point.getAddressDetails());
                pointVo.setCity(point.getCity());
                pointVo.setProvince(point.getProvince());
                pointVo.setDist(point.getDistrict());
                pointVo.setLongitude(point.getLongitude());
                pointVo.setLatitude(point.getLatitude());
                vo.setPoint(pointVo);
            }

            voList.add(vo);
        }
        return voList;
    }

    private UserAddress userAddressValidateAndInit(UserAddressSaveDto saveDto){

        if(StrUtil.isBlank(saveDto.getContactPhone())){
            throw new ApplicationException(ApplicationExceptionEnum.DATA_ERROR.getCode(),"联系电话不能为空");
        }

        SearchFilter filter = SearchFilter.build("createBy", SearchFilter.Operator.EQ, saveDto.getUserId());
        List<UserAddress> record = queryAll(filter);
        UserAddress addressInfo = new UserAddress();
        addressInfo.setAddressDetail(saveDto.getAddressDetail());
        addressInfo.setCreateBy(saveDto.getUserId());
        addressInfo.setCreateTime(new Date());
        addressInfo.setContactName(saveDto.getContactName());
        addressInfo.setContactPhone(saveDto.getContactPhone());
        addressInfo.setOrderBy(CollectionUtils.isEmpty(record) ? 0 : record.size());
        addressInfo.setId(saveDto.getId());
        return addressInfo;
    }

    private MapPoint toMapPoint(MapPointDto pointDto){

        if(StrUtil.isBlank(pointDto.getLongitude()) || StrUtil.isBlank(pointDto.getLatitude())){
            throw new ApplicationException(ApplicationExceptionEnum.DATA_ERROR.getCode(),"请选择地图坐标点");
        }

        MapPoint mapPoint = new MapPoint();
        mapPoint.setLongitude(pointDto.getLongitude());
        mapPoint.setLatitude(pointDto.getLatitude());
        mapPoint.setAddressDetails(pointDto.getAddDetail());
        mapPoint.setProvince(pointDto.getProvince());
        mapPoint.setCity(pointDto.getCity());
        mapPoint.setDistrict(pointDto.getDist());
        mapPoint.setPointType(3);
        return mapPoint;
    }

}
